#include "main.h"
#include "system.h"

ADC_HandleTypeDef Hadc;
DMA_HandleTypeDef Hdma_Adc;
uint16 __align(32) AdcDmaBuf[ADCChanleNumber] = {0};
SampledData __align(32) AdcValBuf[Max_Adc_Time] = {0};

/************************************
ʹ��ADC�Ķ�ʱ������ADCת���Ĺ��ܣ�
Ȼ��ʹ��DMA�������ݵİ��ˣ�����
TIM2��ʱ���Ĵ��������ʵ��ADC��
ʱ����ת���Ĺ��ܣ�Ȼ������ڳ���
����ѭ����һֱ���DMAת����ɱ�־��
Ȼ��������ݵĶ�ȡ������ʹ��DMAת
������жϣ�����ÿ��ת����ɾͻ�����жϡ�
*************************************/
void SysAdcInitial(void)
{

  ADC_ChannelConfTypeDef sConfig = {0};

  /** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) 
  */
  Hadc.Instance = ADC1;
  Hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
  Hadc.Init.Resolution = ADC_RESOLUTION_12B; 
  Hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT; 
  /********************************************
  ��ѡ����Ϊ ENABLE �� DISABLE�������Ƿ�ʹ��ɨ�衣�����
  ��ͨ�� AD ת��ʹ�� DISABLE������Ƕ�ͨ�� AD ת��ʹ�� ENABLE
  ********************************************/
  Hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD; 
  /************************************************
  ��ѡ����Ϊ ADC_EOC_SINGLE_CONV ��
  ADC_EOC_SEQ_CONV �� ָ��ͨ����ѯ���ж���ʹ�� EOC ��־������ EOS ��
  ־����ת��
  *************************************************/
  Hadc.Init.EOCSelection = ADC_EOC_SEQ_CONV;
  Hadc.Init.LowPowerAutoWait = DISABLE; 
  Hadc.Init.LowPowerAutoPowerOff = DISABLE;

  /*****************************************************
  ��ѡ����Ϊ ENABLE �� DISABLE�������������Զ�����
  ת�����ǵ���ת����ʹ�� ENABLE ����Ϊʹ���Զ�����ת����ʹ�� DISABLE ��
  ��Ϊ����ת����ת��һ�κ�ֹͣ��Ҫ�ֶ����Ʋ���������ת����
  ******************************************************/
  
  Hadc.Init.ContinuousConvMode = DISABLE;
  
  
  Hadc.Init.DiscontinuousConvMode = DISABLE; 
  /***********************************************************
  �ⲿ����ѡ�� ͼ 29-1 ���о��˺ܶ��ⲿ�����������ɸ���
  ��Ŀ�������ô�����Դ��ʵ���ϣ�����һ��ʹ�������Զ�������
  ***********************************************************/
  Hadc.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_TRGO; 
  /***************************************************************
  �ⲿ��������ѡ�����ʹ���ⲿ����������ѡ�񴥷���
  ���ԣ���ѡ�н�ֹ������⡢�����ش�����⡢�½��ش�������Լ������غ���
  ���ؾ��ɴ�����⡣
  ****************************************************************/
  Hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
  Hadc.Init.DMAContinuousRequests = ENABLE;
  
  Hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED; 
  if (HAL_ADC_Init(&Hadc) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure for the selected ADC regular channel to be converted. 
  */
  sConfig.Channel = ADC_CHANNEL_0; 
  sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
  sConfig.SamplingTime = ADC_SAMPLETIME_71CYCLES_5;

  if (HAL_ADC_ConfigChannel(&Hadc, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

  sConfig.Channel = ADC_CHANNEL_1; 
  if (HAL_ADC_ConfigChannel(&Hadc, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

  sConfig.Channel = ADC_CHANNEL_2; 
  if (HAL_ADC_ConfigChannel(&Hadc, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

  sConfig.Channel = ADC_CHANNEL_3; 
  if (HAL_ADC_ConfigChannel(&Hadc, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

  sConfig.Channel = ADC_CHANNEL_4; 
  if (HAL_ADC_ConfigChannel(&Hadc, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

  sConfig.Channel = ADC_CHANNEL_5; 
  if (HAL_ADC_ConfigChannel(&Hadc, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sConfig.Channel = ADC_CHANNEL_6; 
  if (HAL_ADC_ConfigChannel(&Hadc, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

  sConfig.Channel = ADC_CHANNEL_7; 
  if (HAL_ADC_ConfigChannel(&Hadc, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

  sConfig.Channel = ADC_CHANNEL_8; 
  if (HAL_ADC_ConfigChannel(&Hadc, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

  sConfig.Channel = ADC_CHANNEL_9; 
  if (HAL_ADC_ConfigChannel(&Hadc, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

  sConfig.Channel = ADC_CHANNEL_13; 
  if (HAL_ADC_ConfigChannel(&Hadc, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

  sConfig.Channel = ADC_CHANNEL_VREFINT;
  if (HAL_ADC_ConfigChannel(&Hadc, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  
  HAL_ADCEx_Calibration_Start(&Hadc);
  HAL_ADC_Start_DMA(&Hadc, (uint32_t *)AdcDmaBuf, ADCChanleNumber);
}

void HAL_ADC_MspInit(ADC_HandleTypeDef *Hadc)
{
  
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if (Hadc->Instance == ADC1)
  {
    __HAL_RCC_ADC1_CLK_ENABLE();
    __HAL_RCC_DMA1_CLK_ENABLE();
    __HAL_RCC_GPIOC_CLK_ENABLE();
    __HAL_RCC_GPIOA_CLK_ENABLE();

    
    GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 |
                          GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    
    GPIO_InitStruct.Pin = GPIO_PIN_3;
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

    
    GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1;
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    
    
    Hdma_Adc.Instance = DMA1_Channel1;
    Hdma_Adc.Init.Direction = DMA_PERIPH_TO_MEMORY;              
    Hdma_Adc.Init.PeriphInc = DMA_PINC_DISABLE;                  
    Hdma_Adc.Init.MemInc = DMA_MINC_ENABLE;                      
    Hdma_Adc.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; 
    Hdma_Adc.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;    
    Hdma_Adc.Init.Mode = DMA_CIRCULAR;                           
    Hdma_Adc.Init.Priority = DMA_PRIORITY_LOW;                   

    if (HAL_DMA_Init(&Hdma_Adc) != HAL_OK)
    {
      Error_Handler();
    }

    __HAL_LINKDMA(Hadc, DMA_Handle, Hdma_Adc);

    HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 3, 0);
    HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
  }
}

void HAL_ADC_MspDeInit(ADC_HandleTypeDef *Hadc)
{
  if (Hadc->Instance == ADC1)
  {
    __HAL_RCC_ADC1_CLK_DISABLE();
    HAL_GPIO_DeInit(GPIOC, GPIO_PIN_3);
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_0);
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_1);
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2);
    HAL_DMA_DeInit(Hadc->DMA_Handle);
  }
}

void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef *hadc) 
{
  if (hadc->Instance == ADC1)
  {
    
  }
}

uint8 AdcDone_Time = 0;
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc) 
{

  if (hadc->Instance == ADC1)
  {
    
    if (++AdcDone_Time == Max_Adc_Time)
    {
      HAL_ADC_Stop_DMA(hadc);
      HAL_ADC_Stop(hadc);
    }
    memcpy((uint8 *)AdcValBuf + (AdcDone_Time - 1) * sizeof(SampledData), (uint8 *)AdcDmaBuf, sizeof(SampledData));

    
  }
}

void ADC1_IRQHandler(void)
{
  
  HAL_ADC_IRQHandler(&Hadc);
}

void DMA1_Channel1_IRQHandler(void)
{
  
  HAL_DMA_IRQHandler(&Hdma_Adc);
}

void StartAdc(void)
{
	
  	HAL_ADCEx_Calibration_Start(&Hadc);
  	HAL_ADC_Start_DMA(&Hadc, (uint32_t *)AdcDmaBuf, ADCChanleNumber);
}
